package com.insist.service.impl;

import com.insist.dao.BrandInfoDao;
import com.insist.dao.ClassInfoDao;
import com.insist.dao.ProductInfoDao;
import com.insist.entity.BrandInfo;
import com.insist.entity.ClassInfo;
import com.insist.entity.ProductInfo;
import com.insist.model.ClassInfoModel;
import com.insist.service.ProductService;
import com.insist.util.BeanCopierUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by INSIST on 2016/6/28.
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private ClassInfoDao classInfoDao;
    @Autowired
    private BrandInfoDao brandInfoDao;

    @Autowired
    private ProductInfoDao productInfoDao;

    @Override
    public List<ClassInfoModel> findAllClass() {
        List<ClassInfoModel> rsList = new ArrayList<>();
        List<ClassInfo> classInfos = classInfoDao.findAll();
        List<BrandInfo> brandInfos = brandInfoDao.findAll();
        Map<Long,List<BrandInfo>> brandMap = new HashMap<>();
        for(BrandInfo info:brandInfos){
            List<BrandInfo> temp = brandMap.get(info.getClassId());
            if(temp==null){
                temp = new ArrayList<>();
                brandMap.put(info.getClassId(), temp);
            }
            temp.add(info);
        }
        for(ClassInfo classInfo:classInfos){
            ClassInfoModel classInfoModel = new ClassInfoModel();
            BeanCopierUtils.copyProperties(classInfo,classInfoModel);
            classInfoModel.setBrandInfos(brandMap.get(classInfo.getId()));
            rsList.add(classInfoModel);
        }
        return rsList;
    }

    @Override
    public List<ProductInfo> findHotProduct() {
        List<ProductInfo> list= productInfoDao.findByIsRecommendAndIsShow(true, 1);
        return list;
    }

    @Override
    public ProductInfo getProductById(Long id) {
        ProductInfo productInfo =  productInfoDao.getOne(id);
        return productInfo;
    }

    @Override
    public List<ProductInfo> findProducts(final Long classId,final Long brandId,final Double startPrice,final Double endPrice) {
        List<ProductInfo> list =  productInfoDao.findAll(new Specification<ProductInfo>(){

            @Override
            public Predicate toPredicate(Root<ProductInfo> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicate = new ArrayList<>();
                if (classId!=null){
                    predicate.add(cb.equal(root.get("classId").as(Long.class), classId));
                }
                if (brandId!=null){
                    predicate.add(cb.equal(root.get("brandId").as(Long.class), brandId));
                }
                if (startPrice!=null){
                    predicate.add(cb.greaterThanOrEqualTo(root.get("price").as(Double.class), startPrice));
                }
                if (endPrice!=null){
                    predicate.add(cb.lessThanOrEqualTo(root.get("price").as(Double.class), endPrice));
                }
                predicate.add(cb.equal(root.get("isShow").as(Integer.class), 1));
                Predicate[] pre = new Predicate[predicate.size()];
                return query.where(predicate.toArray(pre)).getRestriction();
            }
        });
        return list;
    }

    @Override
    public void save(ProductInfo product) {
        productInfoDao.save(product);
    }

    @Override
    public String getMaxProductNo() {
        return productInfoDao.getMaxProductNo();
    }
}
